package com.learn.rpc.socket.proxy;

import com.learn.rpc.common.AdminUser;
import com.learn.rpc.common.AdminUserServiceImpl;
import com.learn.rpc.common.IAdminUserService;

import java.io.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 使用代理的方式实现动态的调用接口返回方法
 * @author wangxing
 * @version 2020/8/14 18:09 Administrator
 */
public class RpcServer2 {
    public static final Integer PORT = 9988;
    private static boolean running = true;
    public static void main(String[] args) throws IOException, ClassNotFoundException, NoSuchMethodException,
            IllegalAccessException, InvocationTargetException {
        ServerSocket serverSocket = new ServerSocket(PORT);
        while(running){
            Socket socket = serverSocket.accept();
//            process(socket);
            processObject(socket);
            socket.close();
        }
    }
    private static void process(Socket socket) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        InputStream in =  socket.getInputStream();
        OutputStream out = socket.getOutputStream();
        ObjectInputStream objectInputStream = new ObjectInputStream(in);
        DataOutputStream dataOutputStream = new DataOutputStream(out);
        String methodName = objectInputStream.readUTF();
        Class[]parameterTypes = (Class[]) objectInputStream.readObject();
        Object[] args = (Object[]) objectInputStream.readObject();

        IAdminUserService service = new AdminUserServiceImpl();
        Method method = service.getClass().getMethod(methodName, parameterTypes);
        AdminUser adminUser = (AdminUser) method.invoke(service, args);
        dataOutputStream.writeInt(adminUser.getId());
        dataOutputStream.writeUTF(adminUser.getName());
        dataOutputStream.flush();

        in.close();
        out.close();
        objectInputStream.close();
        dataOutputStream.close();
    }

    private static void processObject(Socket socket) throws IOException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        InputStream in =  socket.getInputStream();
        OutputStream out = socket.getOutputStream();
        ObjectInputStream objectInputStream = new ObjectInputStream(in);
        ObjectOutputStream objectOutputStream = new ObjectOutputStream(out);
        String methodName = objectInputStream.readUTF();
        Class[]parameterTypes = (Class[]) objectInputStream.readObject();
        Object[] args = (Object[]) objectInputStream.readObject();

        IAdminUserService service = new AdminUserServiceImpl();
        Method method = service.getClass().getMethod(methodName, parameterTypes);
        AdminUser adminUser = (AdminUser) method.invoke(service, args);
        //直接传递object到客户端
        objectOutputStream.writeObject(adminUser);
        objectOutputStream.flush();

        in.close();
        out.close();
        objectInputStream.close();
        objectOutputStream.close();
    }
}
